<template>
  <div>wrapperPromiseRet: {{ wrapperPromiseRet }}</div>
  <div>wrapperPromiseRet2: {{ wrapperPromiseRet2 }}</div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
type RejectMethod = (reason?: any) => void
function buildCancelablePromise<T>(p: Promise<T>) {
  let outReject: undefined | RejectMethod
  const cancelablePromise = new Promise((resolve, reject) => {
    // 这里表示，当p状态改变之后，立刻将cancelablePromise的状态改为相同的状态
    p.then(resolve, reject)
    outReject = reject
  })
  function cancel() {
    console.log('执行cancel', outReject)
    if (outReject) outReject('promise被取消')
  }
  return { cancelablePromise, cancel }
}
const wrapperPromiseRet = ref()
const wrapperPromiseRet2 = ref()

;(() => {
  const p = new Promise<number>(resolve => {
    setTimeout(() => {
      resolve(111)
    }, 3000)
  })

  const wrapperPromise = buildCancelablePromise<number>(p)
  wrapperPromise.cancelablePromise
    .then(ret => {
      console.log('cancelablePromise 执行then', ret)
      wrapperPromiseRet.value = ret
    })
    .catch(e => {
      console.log('cancelablePromise 执行catch', e)
      wrapperPromiseRet.value = e
    })
  wrapperPromise.cancel()

  const p2 = new Promise<number>(resolve => {
    setTimeout(() => {
      resolve(222)
    }, 3000)
  })

  const wrapperPromise2 = buildCancelablePromise<number>(p2)
  wrapperPromise2.cancelablePromise
    .then(ret => {
      console.log('wrapperPromise2的then执行', ret)
      wrapperPromiseRet2.value = ret
    })
    .catch(e => {
      console.log('wrapperPromise2的catch执行', e)
      wrapperPromiseRet2.value = e
    })
})()
</script>

<style scoped></style>
